package com.shao.channelHandler.handler;

import com.shao.compress.CompressorFactory;
import com.shao.serialize.SerializerFactory;
import com.shao.transport.message.RequestPayload;
import com.shao.transport.message.SrpcRequest;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;

import static com.shao.transport.constant.MessageFormatConstant.*;

/**
 * 自定义协议解码器
 * 4B magic(魔数)--->srpc.getBytes()
 * 1B version(版本)----> 1
 * 2B headLength 头部的长度
 * 4B fullLength 报文总长度
 * 1B serialize
 * 1B compress
 * 1B requestType
 * 8B requestId
 * body
 *
 * @author PaoFu
 * @version 1.0
 * @data 2025/4/17 16:06
 */
@Slf4j
public class SrpcRequestDecoder extends LengthFieldBasedFrameDecoder {

    public SrpcRequestDecoder() {
        super(
                // 帧的最大长度。如果帧的长度大于此值，将抛出TooLongFrameException
                MAX_FRAME_LENGTH,
                // 长度字段的偏移量
                MAGIC.length + VERSION_LENGTH + HEAD_FIELD_LENGTH,
                // 长度字段的长度
                FULL_FIELD_LENGTH,
                // 要添加到长度字段值上的补偿值
                -(MAGIC.length + VERSION_LENGTH + HEAD_FIELD_LENGTH + FULL_FIELD_LENGTH),
                // 从解码帧中剥离的第一个字节数
                0
        );
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        Object decode = super.decode(ctx, in);
        if (decode == null) {
            log.warn("解码出的请求对象为空");
            return null;
        }
        if (decode instanceof ByteBuf byteBuf) {
            try {
                return decodeFrame(byteBuf);
            } finally {
                byteBuf.release();
            }
        }
        return null;
    }

    private static Object decodeFrame(ByteBuf byteBuf) {
        SrpcRequest srpcRequest = new SrpcRequest();
        // 魔术值
        byte[] magic = new byte[MAGIC.length];
        byteBuf.readBytes(magic);
        for (int i = 0; i < magic.length; i++) {
            if (magic[i] != MAGIC[i]) {
                throw new RuntimeException("请求不合法");
            }
        }
        // 解析版本号
        byte version = byteBuf.readByte();
        if (version > VERSION) {
            throw new RuntimeException("获得的请求版本不被支持。");
        }
        // 解析头部的长度
        short headLength = byteBuf.readShort();
        // 解析报文的总长度
        int fullLength = byteBuf.readInt();
        // 请求类型 判断是否是心跳检测
        byte reqType = byteBuf.readByte();
        srpcRequest.setRequestType(reqType);
        // 压缩类型
        byte compressType = byteBuf.readByte();
        srpcRequest.setCompressType(compressType);
        // 序列化类型
        byte serializeType = byteBuf.readByte();
        srpcRequest.setSerializeType(serializeType);
        // 请求ID
        long reqId = byteBuf.readLong();
        srpcRequest.setRequestId(reqId);
        // 读取负载
        byte[] payloadByte = new byte[fullLength - headLength];
        byteBuf.readBytes(payloadByte);
        // 解压缩
        byte[] compress = CompressorFactory.getCompressor(compressType).getCompressor().unCompress(payloadByte);
        log.debug("请求解码解压缩成功");
        // 反序列化
        RequestPayload requestPayload = SerializerFactory.getSerializer(serializeType).getSerializer()
                .deserialize(compress, RequestPayload.class);
        srpcRequest.setRequestPayLoad(requestPayload);
        if (log.isDebugEnabled()) {
            log.debug("请求【{}】完成解码", srpcRequest.getRequestId());
        }
        return srpcRequest;
    }
}
